#pragma once

#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <set>
#include <json.hpp>
#include <cinatra.hpp>
#include <vector>
#include "asio_executor.hpp"
#include "client/xd_client.hpp"
#include "room_data_define.hpp"



using namespace cinatra;
using namespace std;


namespace bz {
	class meet;
	class meet_room;

	

	class xd_room :public xd_obs,public AsioExecutor {
	public:
		xd_room(asio::io_context& io , meet_room * room,meet* me, xd_client* xd,int meet_num, terminal* root_ter=nullptr,bool is_main = false, bool auto_invite=false);

		~xd_room();
		
		async_simple::coro::Lazy<void> init();
		void before_del();

		async_simple::coro::Lazy<bool> start_meet();
		async_simple::coro::Lazy<bool> end_meet();

		async_simple::coro::Lazy<bool> roll(terminal* ter);
		async_simple::coro::Lazy<void> cancel_roll();

		async_simple::coro::Lazy<bool> choose(terminal* ter, bool is_poll = false);

		async_simple::coro::Lazy<void> cancel_choose(terminal* ter);
		async_simple::coro::Lazy<void> invite_device(terminal* ter);
		async_simple::coro::Lazy<void> set_audio_mute(terminal* ter, bool mute);
		async_simple::coro::Lazy<void> hungup_device(terminal* ter);
		async_simple::coro::Lazy<void> del_terminal(terminal* ter);

		 
		async_simple::coro::Lazy<bool> change_layout(int picNum, vector<string>& parti_vec);
		


		async_simple::coro::Lazy<void> hungup_link();
		async_simple::coro::Lazy<void> recall_link();
		async_simple::coro::Lazy<void> camera_control(terminal* ter, string cmd, string action);
		async_simple::coro::Lazy<void> set_chairman(terminal* ter);
		async_simple::coro::Lazy<void> choose_parent();
		
		
		async_simple::coro::Lazy<void> hand_all_sound(const bool mute);
		async_simple::coro::Lazy<void> set_default();
		void remove_ter(terminal* ter);
		void set_terminal_list(std::vector<terminal*>& terminal_list);
		bool in_meeting();

		bool get_meet_info();
		json get_participant_status(terminal* ter);
	protected:
		
		void on_msg(const string& meet_name, const string& ter_name, const string& action) override;
	private:

		terminal* name_get_ter(const string& name);
		bool auto_invite_;
		bool link_status_;
		bool shut_down_;
		int meet_num_;
		meet* meet_;
		meet_room* meet_room_;
		xd_client* xd_api_;
		bool is_main_;
		bool is_ready_;
		string obj_id_;
		terminal* root_ter_;
		terminal* parent_room_ter_;

		std::vector<terminal*> *terminal_list_;
		unordered_map<string, terminal*> name_terminal_map_;
		friend class meet_controller;

		friend class serv_manage;
		friend class meet_room;
	};

}